# include"ppForm.h"
# include"Bspline.h"
# include<iostream>
# include<fstream>


using namespace std;

# define Num 201

// 定义函数 f(x)
class Fun : public Function
{
public:
    double operator() (const double & _x) const
    {
        return (1 / (1 + 25 * _x * _x));
    }
};

// 测试程序
int main()
{
    Fun fun;
    vector<int> N{6, 11, 21, 41, 81};
    int n = N.size();
    double eps = 2.0 / 200;

    ofstream foutpp, foutB;
    foutpp.open("data/proAppForm.txt", ios::out);
    foutB.open("data/proABspline.txt", ios::out);

    vector<double> maxerrorpp, maxerrorB;
    for(int i = 0; i < n; i++)
    {
        double errorpp, errorB;
        double knots = 2.0 / (N[i] - 1);
        vector<double> point;
        for (int j = 0; j < N[i]; j++)
        {
            point.push_back(-1 + j * knots);
        }

        // Use ppForm to estimate.
        ppForm ppA(S32, point, fun, Complete);
        // Curve
        for (int j = 0; j < 201; j++)
        {
            foutpp << ppA.solve(-1 + j * eps) << " ";
        }
        foutpp << endl;
        // Error
        errorpp = fabs(fun(-1 + 0.5 * knots) - ppA.solve(-1 + 0.5 * knots));
        for (int j = 1; j < N[i] - 1; j++)
        {
            double err = fabs(fun(-1 + (0.5 + j) * knots) - ppA.solve(-1 + (0.5 + j) * knots));
            if(err > errorpp) errorpp = err;
        }
        maxerrorpp.push_back(errorpp);

        // Use Bspline to estimate.
        Bspline BspA(S32, point, fun, Complete);
        // Curve
        for (int j = 0; j < 201; j++)
        {
            foutB << BspA.solve(-1 + j * eps) << " ";
        }
        foutB << endl;
        // Error
        errorB = fabs(fun(-1 + 0.5 * knots) - BspA.solve(-1 + 0.5 * knots));
        for (int j = 1; j < N[i] - 1; j++)
        {
            double err = fabs(fun(-1 + (0.5 + j) * knots) - BspA.solve(-1 + (0.5 + j) * knots));
            if(err > errorB) errorB = err;
        }
        maxerrorB.push_back(errorB);
    }

    // Output the maximal error of each N
    ofstream foutresult;
    foutresult.open("result/ProAmaxerr.txt", ios::out);
    foutresult << "N, maxerr of ppForm, maxerr of Bspline" << endl;
    for (int i = 0; i < n; i++)
    {
        foutresult << N[i] << ",     " << maxerrorpp[i] << ",     " << maxerrorB[i] << endl;
    }
    foutresult.close();

    foutpp.close();
    foutB.close();

    cout << "Finish Pro A." << endl;

    return 0;
}